package com.ttflutter.tkvideodownloader.api

import android.text.TextUtils
import com.alibaba.fastjson.JSON
import com.google.gson.Gson
import okhttp3.MediaType
import okhttp3.RequestBody
import okhttp3.ResponseBody
import okio.Buffer
import org.json.JSONObject
import retrofit2.Converter
import retrofit2.Retrofit
import java.io.BufferedReader
import java.io.OutputStreamWriter
import java.lang.reflect.Type
import java.nio.charset.Charset

/**
 * @author Afra55
 * @date 2019-06-19
 * A smile is the best business card.
 */
class ResponseConverterFactory(var jsonObject: JSONObject, var mediaTypeStr: String?) : Converter.Factory() {

    companion object {
        @JvmStatic
        fun create(): ResponseConverterFactory {
            return create(JSONObject(), null)
        }

        @JvmStatic
        fun create(mediaType: String?): ResponseConverterFactory {
            return create(JSONObject(), mediaType)
        }

        @JvmStatic
        private fun create(jsonObject: JSONObject, mediaType: String?): ResponseConverterFactory {
            return ResponseConverterFactory(jsonObject, mediaType)
        }
    }

    override fun responseBodyConverter(
        type: Type,
        annotations: Array<Annotation>,
        retrofit: Retrofit
    ): Converter<ResponseBody, *>? {
        return JsonResponseBodyConverter(type)
    }

    override fun requestBodyConverter(
        type: Type,
        parameterAnnotations: Array<Annotation>,
        methodAnnotations: Array<Annotation>,
        retrofit: Retrofit
    ): Converter<*, RequestBody>? {
        return JsonRequestBodyConverter(mediaTypeStr)
    }

}

class JsonResponseBodyConverter(var type: Type) : Converter<ResponseBody, Any>{


    override fun convert(value: ResponseBody): Any? {
        try {
            val br = BufferedReader(value.charStream())
            var line:String?
            val buffer = StringBuilder()
            while (true) {
                line = br.readLine()
                if (line != null) {
                    buffer.append(line)
                } else {
                    break
                }
            }

            return parseObject(buffer.toString(), type)
        } catch (e: Exception) {
            e.printStackTrace()
        }

        return null

    }
    fun  parseObject(str: String, clazz: Type): Any {
        try {

            try {
                return JSON.parseObject(str, clazz)
            } catch (e: Exception) {
                return Gson().fromJson(str, clazz)
            }
        } catch (e: Exception) {
            e.printStackTrace()
        }

        return str
    }
}

class JsonRequestBodyConverter(var mediaTypeStr:String? = null) : Converter<Any, RequestBody>{

    override fun convert(value: Any): RequestBody? {
        try {
            if (value is RequestBody) {
                return value
            }
            val buffer = Buffer()
            val writer = OutputStreamWriter(buffer.outputStream(), Charset.forName("UTF-8"))
            writer.write(value.toString())
            writer.close()
            var mediaType: MediaType?
            if (TextUtils.isEmpty(mediaTypeStr)) {
                mediaType = MediaType.parse("application/json; charset=UTF-8")
            } else {
                try {
                    mediaType = MediaType.parse(mediaTypeStr)
                } catch (e: Exception) {
                    mediaType = MediaType.parse("application/json; charset=UTF-8")
                }
            }
            return RequestBody.create(mediaType, buffer.readByteString())
        } catch (e: Exception) {
            e.printStackTrace()
        }
        return null
    }

}